#include "AssetWriter.h"

namespace XpsAssets
{

AssetWriter::AssetWriter(void)
{
}

AssetWriter::~AssetWriter(void)
{
}

void AssetWriter::write(QString filename)
{
	// Write as XML
	QFile file(filename);
	
	if (!file.open(QFile::WriteOnly | QFile::Text))
		qDebug() << "error";

	xmlout.setDevice(&file);
	xmlout.setAutoFormatting(true);
	
	// header
	xmlout.writeStartDocument();
	xmlout.writeDTD("<!DOCTYPE xps>");
	xmlout.writeStartElement("xps");
	xmlout.writeAttribute("version", "1.0");

	// content
	xmlout.writeStartElement("assets");

	writeAttributesPool();
	writeQuestionsPool();
	writeResults();
	writeTreeNodes();

	// end
	xmlout.writeEndDocument();
	file.close();
}

//#######################//
// WRITE RESULTS//
//#######################//
void AssetWriter::writeResults()
{
	xmlout.writeStartElement("results");
	xmlout.writeAttribute("count", QString("%1").arg(results.count()) );

	for (int i = 0; i < results.count(); i++)
	{
		Result* r = results.at(i);

		xmlout.writeStartElement("result");
		xmlout.writeAttribute("id", QString("%1").arg(r->id()) );
		
		xmlout.writeAttribute("name", r->name());
		xmlout.writeAttribute("mediapath", r->mediapath());
		xmlout.writeAttribute("description", r->desc());

		// Write Attributes
		for (int j = 0; j < r->attributes()->count(); j++)
		{
			int id = r->attributes()->keys().at(j);
			ResultAttribute* ra = r->attributes()->value(id);

			xmlout.writeStartElement("attribute");
			xmlout.writeAttribute("id", QString("%1").arg(id));
			xmlout.writeAttribute("matchmode", QString("%1").arg(ra->matchMode()));
			xmlout.writeAttribute("value", QString("%1").arg(ra->value()));
			if (ra->matchMode() != XpsAssets::EXACT)
				xmlout.writeAttribute("tolerance", QString("%1").arg(ra->tolerance()));
			
			xmlout.writeEndElement();
		}
		xmlout.writeEndElement();
	}
	xmlout.writeEndElement();
}

//#######################//
// WRITE ATTRIBUTES POOL //
//#######################//
void AssetWriter::writeAttributesPool()
{

	xmlout.writeStartElement("attributes");
	xmlout.writeAttribute("count", QString("%1").arg(attributes.count()) );

	for (int i = 0; i < attributes.count(); i++)
	{
		xmlout.writeStartElement("attribute");
		xmlout.writeAttribute("id", QString("%1").arg(attributes.at(i)->id()) );
		
		xmlout.writeAttribute("name", attributes.at(i)->name());
		xmlout.writeAttribute("description", attributes.at(i)->desc());
		xmlout.writeAttribute("weight", QString("%1").arg(attributes.at(i)->weight()) );
		xmlout.writeEndElement();
	}
	xmlout.writeEndElement();
}

//######################//
// WRITE QUESTIONS POOL //
//######################//
void AssetWriter::writeQuestionsPool()
{
	xmlout.writeStartElement("questions");
	xmlout.writeAttribute("count", QString("%1").arg(questions.count()) );

	for (int i = 0; i < questions.count(); i++)
	{
		Question* q = questions.at(i);

		// Write Question Data
		xmlout.writeStartElement("question");
		xmlout.writeAttribute("id", QString("%1").arg(q->id()) );
		xmlout.writeAttribute("mode",QString("%1").arg(q->choiceMode()));
		xmlout.writeAttribute("text", q->text() );		

		// Write Question Responses Data
		for (int j = 0; j < q->responses()->count(); j++)
		{
			Response* r = responses.get(q->responses()->at(j));
			xmlout.writeStartElement("response");
			xmlout.writeAttribute("text", r->text() );
			
			// Write Response Attributes
			for (int k = 0; k < r->attributes()->count(); k++)
			{
				int id = r->attributes()->keys().at(k);
				ResponseAttribute* ra = r->attributes()->value(id);
				
				xmlout.writeStartElement("attribute");
				xmlout.writeAttribute("id", QString("%1").arg(id));
				xmlout.writeAttribute("value", QString("%1").arg(ra->value()));
				xmlout.writeEndElement();
			}
			xmlout.writeEndElement();
		}
		xmlout.writeEndElement();
	}
	xmlout.writeEndElement();
}

//##################//
// WRITE TREE NODES //
//##################//
void AssetWriter::writeTreeNodes()
{
	TreeNode* node = NULL;
	ConstraintNode* cnode = NULL;

	xmlout.writeStartElement("tree");

	for (int i = 0; i < tree.count(); i++)
	{
		node = tree.at(i);

		// write universal tree node attributes
		xmlout.writeStartElement(node->typeString());
		xmlout.writeAttribute("id", QString("%1").arg(node->_id));
		
		// write node position (except for link node)
		if (node->_type != TreeNode::LINK) 
		{
			xmlout.writeAttribute("x", QString("%1").arg(node->_position.x()) );
			xmlout.writeAttribute("y", QString("%1").arg(node->_position.y()) );
		}

		switch (node->_type)
		{
		case TreeNode::START:
		case TreeNode::END:
				break;
			
		// write link tree node
		case TreeNode::LINK:

			if (node->_mode == 1)
				xmlout.writeAttribute("case", "true");
			else if (node->_mode == 2)
				xmlout.writeAttribute("case", "false");

			xmlout.writeAttribute("parent", QString("%1").arg(node->_parent) );
			xmlout.writeAttribute("child", QString("%1").arg(node->_child) );
			break;

		// write question tree node
		case TreeNode::QUESTION:
			xmlout.writeAttribute("qid", QString("%1").arg(node->_refId));
			break;

		// write constraint tree node
		case TreeNode::CONSTRAINT:
			
			cnode = (ConstraintNode*) node;

			if (cnode->_true != 0)
				xmlout.writeAttribute("true", QString("%1").arg(cnode->_true));
			if (cnode->_false != 0)
				xmlout.writeAttribute("false", QString("%1").arg(cnode->_false));

			for (int k = 0; k < cnode->attributes.count(); k++)
			{
				int id = cnode->attributes.keys().at(k);
				ConstraintAttribute* ca = cnode->attributes.value(id);

				xmlout.writeStartElement("attribute");
				xmlout.writeAttribute("id", QString("%1").arg(id));
				xmlout.writeAttribute("compareMode", QString("%1").arg(ca->compareMode()));
				xmlout.writeAttribute("value", QString("%1").arg(ca->value()));
				xmlout.writeEndElement();
			}
			break;

		default:
			qDebug() << "error";
			break;
		}
		xmlout.writeEndElement();
	}
	xmlout.writeEndElement();
}

}